<template>
    <div>
        <h-cascader
            :changeOnSelect="changeOnSelect"
            placeholder="请选择"
            :options="treeData"
            labelField="catalogName"
            valueField="catalogCode"
            show-search
            childrenField="subNodes"
            ref="cascaderRef"
            @change="handleCascaderChange"
        />
    </div>
</template>

<script lang="ts">
import { treeFilter, getMenuId } from '@/utils/tree';
import api from '@/api';
import { deepClone } from '@/utils/util';
import { HCascader } from '@/components';
import { defineComponent, ref, unref, reactive, toRefs, onMounted, watch } from 'vue';
export default defineComponent({
    components: {
        HCascader
    },
    props: {
        value: {
            type: String,
            default: ''
        },
        changeOnSelect: {
            type: Boolean,
            default: false
        },
        defaultTreeData: {
            type: Array,
            default: () => []
        }
    },
    emits: ['update:value', 'change'],
    setup(props, { emit }) {
        const cascaderRef = ref<any>();
        const state = reactive<any>({
            treeData: [],
            isEmpty: false,
            cascaderValue: []
        });
        const transformDataByFlatProperty = (data, fields = { keyField: 'node', childrenField: 'subNodes' }) => {
            const { keyField, childrenField } = fields;
            data.forEach((item, index) => {
                data[index] = {
                    ...data[index],
                    ...data[index][keyField],
                    catalogName: data[index][keyField].catalogName
                };
                if (item[childrenField] && item[childrenField].length) {
                    data[index][childrenField] = transformDataByFlatProperty(item[childrenField], fields);
                } else {
                    data[index][childrenField] = null;
                }
            });
            return data;
        };
        // tab列表
        const getTreeData = async () => {
            const query = {
                type: 2
            };
            const { success, moule } = await api.portalControlModel.getSystemProductCatalogTreeData(query);
            if (success) {
                if (moule) {
                    const treeData = transformDataByFlatProperty(deepClone(JSON.parse(moule)));
                    // 获取完整树节点
                    const target: any = treeFilter(treeData, (node) => node.node.catalogCode === props.value);
                    // 获取产品线节点
                    const parentNode = treeData.find((item) => item.node.catalogCode === target[0].node.catalogCode);
                    // 筛选出产品树
                    const subTree = parentNode.subNodes.find((item) => item.node.catalogCode === target[0].subNodes[0].node.catalogCode);
                    state.treeData = deepClone([subTree]);
                    updateCascaderValue();
                } else {
                    state.isEmpty = true;
                }
            }
        };

        getTreeData();

        const handleCascaderChange = ({ nodeArr, nodeInfo }) => {
            state.cascaderValue = nodeArr[nodeArr.length - 1];
            emit('update:value', nodeArr[nodeArr.length - 1]);
            emit('change', { nodeArr, nodeInfo });
        };

        const handleClear = () => {
            unref(cascaderRef) && unref(cascaderRef).handleClear();
        };
        // 更新
        const updateCascaderValue = () => {
            if (state.treeData.length) {
                const target: any = treeFilter(state.treeData, (node) => node.node.catalogCode === props.value);
                if (target && target[0]) {
                    state.cascaderValue = getMenuId(target[0]);
                    setTimeout(() => {
                        if (unref(cascaderRef)) {
                            unref(cascaderRef).value = state.cascaderValue;
                        }
                    });
                }
            }
        };
        watch(
            () => props.value,
            () => {
                if (JSON.stringify(state.cascaderValue) !== JSON.stringify(props.value)) {
                    updateCascaderValue();
                }
            },
            {
                immediate: true
            }
        );

        onMounted(() => {
            handleClear();
        });

        return {
            cascaderRef,
            ...toRefs(state),
            handleCascaderChange,
            handleClear
        };
    }
});
</script>

<style scoped>
</style>